package com.zhj.rabbitmq.demo;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @program: rabbimmq-demo
 * @description: 接收消息
 * @author: zhengjibin
 * @create: 2020-11-16 16:02
 * @Version 1.0
 **/
public class ReceiveMessage {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("122.112.198.94");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("admin");
        //与 发送消息端 一直
        Connection connection = null;// 定义rabbitmq的网络连接 ，一个连接
        Channel channel = null;//定义一个链接中的通道
        connection = factory.newConnection();//通过工厂获得连接
        channel = connection.createChannel();//通过连接获得通道

        String queueName = "demo1_queue";
        //channel.queueDeclare(queueName,true,false,false,null);//生成消息队列 。可以在消费端创建队列，也能在生产端创建队列。
                                                                //如果消费端创建队列，那么在消费端执行之前，生成端不能发送消息，否则会消息丢失
        /*
            接收指定队列消息
            参数1：队列名称
            参数2：是否自动确认，true表示自动确认，接收完消息后会自动将队列中的消息删除。false则要手动删除消息
            参数3：为消息消费者的标签，多个消费者监听一个消息队列时，通过这个标签区分哪些消费者能消费，一般不这样用
            参数4：接收消息的回调，这个参数中实现的方法会去一直监听消息队列获取消息
         */
        channel.basicConsume(queueName,true,"",new DefaultConsumer(channel){
            //重写 DefaultConsumer 中的方法
            /*
                参数1：消息标签
                参数2：消息对象
                参数3：消息属性信息
                参数4：消息具体内容
                注意：DefaultConsumer 方法使用后，会启动一个线程，异步的持续监听消息队列，如果队列中有消息会自动接收
                    所以不能关闭channel和connection 对象
             */
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //super.handleDelivery(consumerTag, envelope, properties, body);
                String message = new String(body,"UTF-8");
                System.out.println(message);
            }
        });

        //channel.close(); 消费端，不能关闭通道，和连接，如果关闭了。会造成接收时抛出异常，或者接收不到消息
        //connection.close();
    }
}
